//
//  types.swift
//  swift_ example
//
//  Created by 魏熙美 on 2020/2/22.
//  Copyright © 2020 魏熙美. All rights reserved.
//

import Foundation

// 类型转换: 类型向下转换, 类型判断

// Swift 为不确定的类型提供了两种特殊的类型别名：
// - AnyObject  可以表示任何类类型的实例。
// - Any  可以表示任何类型，包括函数类型。

func anys() {
    // Any  可以表示任何类型，包括函数类型。
    var any = [Any]()
    any.append(0)
    any.append("aaa")
    any.append({ (name: String) -> String in "weiximei" })
    any.append(Movie(name: "zhangsan", director: "ddd"))
    any.append(Song(name: "ffdd", artist: "fdfd"))
    
    // AnyObject  可以表示任何类类型的实例
    var anyObject = [AnyObject]()
    anyObject.append(Movie(name: "zhangsan", director: "ddd"))
    anyObject.append(Song(name: "ffdd", artist: "fdfd"))
    
    // as 类型转换：向下转型
    for thing in any {
        switch thing {
        case 0 as Int:
            print("zero as an Int")
        case 0 as Double:
            print("zero as a Double")
        case let someInt as Int:
            print("an integer value of \(someInt)")
        case let someDouble as Double where someDouble > 0:
            print("a positive double value of \(someDouble)")
        case is Double:
            print("some other double value that I don't want to print")
        case let someString as String:
            print("a string value of \"\(someString)\"")
        case let (x, y) as (Double, Double):
            print("an (x, y) point at \(x), \(y)")
        case let movie as Movie:
            print("a movie called \(movie.name), dir. \(movie.director)")
        case let stringConverter as (String) -> String:
            print(stringConverter("Michael"))
        default:
            print("something else")
        }
    }
}


// 定义一个基类
class MediaItem {
    var name: String
    init(name: String) {
        self.name = name
    }
}

// 定义子类
class Movie: MediaItem {
    var director: String
    init(name: String, director: String) {
        self.director = director
        super.init(name: name)
    }
}

// 定义子类
class Song: MediaItem {
    var artist: String
    init(name: String, artist: String) {
        self.artist = artist
        super.init(name: name)
    }
}

// 都有一个共同的父类，所有类型可以说一样的, 可以放进数组
let library = [
    Movie(name: "Casablanca", director: "Michael Curtiz"),
    Song(name: "Blue Suede Shoes", artist: "Elvis Presley"),
    Movie(name: "Citizen Kane", director: "Orson Welles"),
    Song(name: "The One And Only", artist: "Chesney Hawkes"),
    Song(name: "Never Gonna Give You Up", artist: "Rick Astley")
]
// "library" 的类型被推断为[MediaItem]

func runClass() {
    // 统计个数
    var movieCount = 0
    var songCount = 0
    
    // 循环判断类型
    for item in library {
        
        // 判断类型
        if item is Movie {
            movieCount += 1
        } else if item is Song {
            songCount += 1
        }
        
    }
    
    // 类型向下转换
    for item in library {
        // 尝试 item 转换为子类 Movie类型, 如果成功则赋值给 movie
        // 不成功则返回一个 nil，通过 if 这个语法糖, 可以自动判断是否 nil
        if let movie = item as? Movie {
            print("movie: \(movie.director), \(movie.name)")
        } else if let song = item as? Song {
            print("song: \(song.artist), \(song.name)")
        }
    }
    
    print("movie有\(movieCount)个，song有\(songCount)个")
}

